package simpleGeom;

import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Collections;
import java.util.Vector;

public class Intersection2D implements Comparable{
	HasLine2D line1;
	HasLine2D line2;
	float t1;
	float t2;
	float x;
	float y;
	
	public HasLine2D getLine1() {
		return line1;
	}
	public void setLine1(HasLine2D line1) {
		this.line1 = line1;
	}
	public HasLine2D getLine2() {
		return line2;
	}
	public void setLine2(HasLine2D line2) {
		this.line2 = line2;
	}
	public float getT1() {
		return t1;
	}
	public void setT1(float t1) {
		this.t1 = t1;
	}
	public float getT2() {
		return t2;
	}
	public void setT2(float t2) {
		this.t2 = t2;
	}


	public int compareTo(Object o) {
		Intersection2D i=(Intersection2D)o;
		return Float.compare(getT1(),i.getT1());
	}
	public float getX() {
		return x;
	}
	public void setX(float x) {
		this.x = x;
	}
	public float getY() {
		return y;
	}
	public void setY(float y) {
		this.y = y;
	}

	public static Vector<Intersection2D> getRaySegIntersections(HasLine2D l,
			Vector<? extends HasLine2D> lines) {
		Vector<Intersection2D> intersections=new Vector<Intersection2D>();
		for (int i=0;i<lines.size();i++){
			HasLine2D cL=lines.get(i);
			Intersection2D cI=getRaySegIntersection(l,cL);
			if (cI!=null){
				intersections.add(cI);
			}
		}
		if (intersections.size()>0){
			Collections.sort(intersections);
			return intersections;
		}
		return null;
	}
	public static Vector<Intersection2D> getSegSegIntersections(HasLine2D l,
			Vector<? extends HasLine2D> lines) {
		Vector<Intersection2D> intersections=new Vector<Intersection2D>();
		for (int i=0;i<lines.size();i++){
			HasLine2D cL=lines.get(i);
			Intersection2D cI=getSegSegIntersection(l,cL);
			if (cI!=null){
				intersections.add(cI);
			}
		}
		if (intersections.size()>0){
			Collections.sort(intersections);
			return intersections;
		}
		return intersections;
	}
	
	public static Intersection2D getRaySegIntersectionClosest(HasLine2D l,
			Vector<? extends HasLine2D> lines){
		Vector<Intersection2D> intersections=getRaySegIntersections(l,lines);
		if (intersections==null)return null;
		else return intersections.firstElement();
	}
	public static Vector<Intersection2D> getLineSegIntersections(HasLine2D l,
			Vector<HasLine2D> lines) {
		Vector<Intersection2D> intersections=new Vector<Intersection2D>();
		for (int i=0;i<lines.size();i++){
			HasLine2D cL=lines.get(i);
			Intersection2D cI=getLineSegIntersection(l,cL);
			if (cI!=null){
				intersections.add(cI);
			}
		}
		if (intersections.size()>0){
			Collections.sort(intersections);
		}
		return null;
	}

	public static Vector<Intersection2D> getAllIntersectionSeg(HasLine2D l,
			Vector<HasLine2D> lines) {
		return null;
	}

	public static Intersection2D getLineLineIntersection(HasLine2D l1,
			HasLine2D l2) {
		float aX = l1.getX1();
		float aY = l1.getY1();
		float bX = l1.getX2();
		float bY = l1.getY2();

		float cX = l2.getX1();
		float cY = l2.getY1();
		float dX = l2.getX2();
		float dY = l2.getY2();

		float denominator = ((bX - aX) * (dY - cY)) - ((bY - aY) * (dX - cX));
		if (denominator == 0){
			
			return null;// parallel
		}
		float numerator = ((aY - cY) * (dX - cX)) - (aX - cX) * (dY - cY);
		float numerator2 = ((aY - cY) * (bX - aX)) - ((aX - cX) * (bY - aY));
		float r = numerator / denominator;
		float s = numerator2 / denominator;
		float x = aX + r * (bX - aX);
		float y = aY + r * (bY - aY);

		Intersection2D intersection = new Intersection2D();
		intersection.setLine1(l1);
		intersection.setLine2(l2);
		intersection.setT1(r);
		intersection.setT2(s);
		intersection.x=x;
		intersection.y=y;
		return intersection;
	}

	public static Intersection2D getRaySegIntersection(HasLine2D l1, HasLine2D l2) {
		Intersection2D i = getLineLineIntersection(l1, l2);
		if (i == null)
			return null;
		if (i.getT1() < 0)
			return null;
		if (i.getT2() < 0 || i.getT2() > 1)
			return null;
		return i;
	}
	public static Intersection2D getLineSegIntersection(HasLine2D l1, HasLine2D l2) {
		Intersection2D i = getLineLineIntersection(l1, l2);
		if (i == null)
			return null;
		if (i.getT2() < 0 || i.getT2() > 1)
			return null;
		return i;
	}
	
	public static Intersection2D getSegSegIntersection(HasLine2D l1, HasLine2D l2) {
		Intersection2D i = getLineLineIntersection(l1, l2);
		if (i == null)
			return null;
		if (i.getT1() < 0||i.getT1()>1)
			return null;
		if (i.getT2() < 0 || i.getT2() > 1)
			return null;
		return i;
	}
	
	

}